package framework.utils;

import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLSocketFactory;

/**
 * Inet connection.
 *
 * @author	Orlin Tomov
 * @version	0.2
 */
public class Conn {

	protected String host;
	protected int port;
	protected boolean ssl;

	protected Socket socket;
	protected InputStream in;
	protected OutputStream out;
	/** min * sec * ms */
	private static final int timeout = 2 * 60 * 1000;

	public Conn(String host, int port) throws IOException {
		this(host, port, false);
	}

	public Conn(String host, int port, boolean ssl) throws IOException {
		this.host = host;
		this.port = port;
		this.ssl = ssl;
		connect();
	}

	/**
	 * @param	socket
	 * @throws	IOException
	 */
	public Conn(Socket socket) throws IOException {
		this.socket = socket;
		this.in = socket.getInputStream();
		this.out = socket.getOutputStream();
		this.host = socket.getInetAddress().getHostAddress();
		this.port = socket.getPort();
	}

	public void connect() throws IOException {
		if (!isConnected()) {
			InetAddress address = resolve();
			if (ssl) {
				socket = SSLSocketFactory.getDefault().createSocket(address, port);
			} else {
				socket = new Socket(address, port);
			}
			socket.setKeepAlive(false);
			socket.setSoTimeout(timeout);
			// socket.setSoLinger(false, 120);
			in();
			out();
		}
	}

	private InetAddress resolve() throws UnknownHostException {
		InetAddress address = InetAddress.getByName(getHost());
		return address;
	}

	private void in() throws IOException {
		in = socket.getInputStream();
	}

	private void out() throws IOException {
		out = socket.getOutputStream();
	}

	/**
	 * @return	the port.
	 */
	public int getPort() {
		return port;
	}

	/**
	 * @return the in.
	 */
	public InputStream getInputStream() {
		if (isConnected()) {
			return in;
		} else {
			return null;
		}
	}

	/**
	 * @return	the out.
	 */
	public OutputStream getOutputStream() {
		if (isConnected()) {
			return out;
		} else {
			return null;
		}
	}

	public String getHost() {
		if (isConnected()) {
			return socket.getInetAddress().getHostName();
		} else {
			return host;
		}
	}

	public String getIP() {
		if (isConnected()) {
			return socket.getInetAddress().getHostAddress();
		} else {
			return null;
		}
	}

	/**
	 * @return Returns the socket.
	 */
	public Socket getSocket() {
		if (isConnected()) {
			return socket;
		} else {
			return null;
		}
	}

	public void close() throws IOException {
		in = null;
		out = null;
		if (socket != null) {
			Socket temp = socket;
			socket = null;
			temp.close();
		}
	}

	public boolean isConnected() {
		return ((socket != null) && socket.isConnected());
	}
}
